/*
* File: CFpEventFactory.h
* Copyright (c) 2010. Silviu Caragea <silviu@intelliproject.net>
* Created on  September 9, 2010, 5:10 PM
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*  1.Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*  2.Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
*  3.All advertising materials mentioning features or use of this software
*    must display the following acknowledgement:
*       This product includes software developed by the University of
*       California, Berkeley and its contributors.
*  4.Neither the name of the University nor the names of its contributors
*    may be used to endorse or promote products derived from this software
*    without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef CFDEVENTFACTORY_H
#define	CFDEVENTFACTORY_H

#include "../utils/CLogger.h"
#include "IFdEventInterface-Inl.h"

#ifdef USE_SELECT
    #include "event/CFdEventSelect.h"
#endif

#ifdef USE_POLL
    #include "event/CFdEventPoll.h"
#endif

#ifdef USE_KQUEUE
    #include "event/CFdEventKQueue.h"
#endif

#ifdef USE_EPOLL
    #include "event/CFdEventEpoll.h"
#endif

#ifdef USE_SOLARIS_DEVPOLL
    #include "event/CFdEventDevPoll.h"
#endif

namespace litevent
{

class CFdEventFactory 
{
public:

    static IFdEventInterface * CreateInstance(EnumEventHandlerType type, size_t maxfds = 4096)
    {
        switch (type)
        {
            case EnumEventHandlerTypeUnset:
            {
                return NULL; 
            }

            case EnumEventHandlerTypeSelect:
            {
#ifdef USE_SELECT
                if(maxfds > FD_SETSIZE )
                {
                    util::CLogger::sharedLogger()->WriteFormated("%s.%d: Maximum file descriptors over FD_SETSIZE.", __FILE__, __LINE__);
                    maxfds = FD_SETSIZE ;
                }

                return new CFdEventSelect(maxfds);
#else
                CLogger::sharedLogger()->WriteFormated("%s.%d: Not compiled with HAVE_SELECT", __FILE__, __LINE__);
                return NULL;
#endif
            }

            case EnumEventHandlerTypePoll:
            {
#ifdef USE_POLL
                return new CFdEventPoll(maxfds);
#else
                util::CLogger::sharedLogger()->WriteFormated("%s.%d: Not compiled with HAVE_POLL", __FILE__, __LINE__);
                return NULL;
#endif
            }

            case EnumEventHandlerTypeKqueue:
            {
#ifdef USE_KQUEUE
                CFdEventKQueue *kQueue = NULL;

                try
                {
                        kQueue = new CFdEventKQueue(maxfds);
                }
                catch(util::CException ex)
                {
                    SafeReleasePtr(kQueue);
                }	
				
		return kQueue;
#else
                util::CLogger::sharedLogger()->WriteFormated("%s.%d: Not compiled with HAVE_KQUEUE", __FILE__, __LINE__);
                return NULL;
#endif
            }

            case EnumEventHandlerTypeEpoll:
            {
#ifdef USE_EPOLL

                CFdEventEpoll *epoll = NULL;

                try
                {
                    epoll = new CFdEventEpoll(maxfds);
                }
                catch(util::CException ex)
                {
                    SafeReleasePtr(epoll);
                }

                return epoll;

#else
                util::CLogger::sharedLogger()->WriteFormated("%s.%d: Not compiled with HAVE_SYS_EPOLL_H", __FILE__, __LINE__);
                return NULL;
#endif
            }

            case EnumEventHandlerTypeDevPoll:
            {
#ifdef USE_SOLARIS_DEVPOLL

                CFdEventDevPoll *devPoll = NULL;

                try
                {
                    devPoll = new CFdEventDevPoll(maxfds);
                }
                catch(util::CException ex)
                {
                    SafeReleasePtr(devPoll);
                }

                return devPoll;

#else
                util::CLogger::sharedLogger()->WriteFormated("%s.%d: Not compiled with HAVE_SYS_DEVPOLL_H", __FILE__, __LINE__);
                return NULL;
#endif
            }

        }

        return NULL;
    }

};

}
#endif	/* CFDEVENTFACTORY_H */

